﻿using System;
using System.IO;

namespace UFrame
{
    public class NetWork
    {
        private Connector mConnector = null;
        private Protocol mProtocol = null;

        private string mIP = "";
        private int mPort = 0;

        public string IP
        {
            get { return mIP; }
        }

        public int Port
        {
            get { return mPort; }
        }

        public bool IsWorking
        {
            get { return (mConnector != null && mConnector.IsWorking()); }
        }

        public void StartNetWork(string ip, int port)
        {
            mIP = ip;
            mPort = port;

            if (mProtocol == null)
            {
                mProtocol = new Protocol();
                InitialProtocol();
            }

            if (mConnector == null)
            {
                mConnector = new Connector(mIP, mPort);
                mConnector.OnConnected += new EventHandler<EventArgs>(OnConnected);
                mConnector.OnConnectFailed += new EventHandler<EventArgs>(OnConnectFailed);
                mConnector.OnDisconnected += new EventHandler<EventArgs>(OnDisconnected);
                mConnector.OnReceived += new EventHandler<NetEventArg_Received>(ReceiveProtocol);
                mConnector.StartConnect();
            }
        }

        public void StopNetWork()
        {
            if (mProtocol != null)
            {
                mProtocol = null;
            }

            if (mConnector != null)
            {
                mConnector.OnConnected -= new EventHandler<EventArgs>(OnConnected);
                mConnector.OnConnectFailed -= new EventHandler<EventArgs>(OnConnectFailed);
                mConnector.OnDisconnected -= new EventHandler<EventArgs>(OnDisconnected);
                mConnector.OnReceived -= new EventHandler<NetEventArg_Received>(ReceiveProtocol);

                if (!mConnector.IsStopped())
                {
                    mConnector.CloseConnect();
                }

                mConnector = null;
            }
        }

        public void Update()
        {
            if (mProtocol != null)
            {
                mProtocol.ProcessMsg();
            }

            if (mConnector != null)
            {
                mConnector.Update();
            }
        }

        private void SendData(byte[] byData)
        {
            if (mConnector != null)
            {
                mConnector.SendToServer(byData);
            }
        }

        public void SendRPC(ushort op)
        {
            int headLen = NetDefine.HEAD_LEN_SIZE;
            byte[] data = new byte[headLen + NetDefine.HEAD_OP_SIZE];
            BitConverter.GetBytes(0).CopyTo(data, 0);
            BitConverter.GetBytes(op).CopyTo(data, headLen);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(data, 0, headLen);
                Array.Reverse(data, headLen, NetDefine.HEAD_OP_SIZE);
            }
            SendData(data);
        }

        public void SendRPC<T>(ushort op, T rpc)
        {
            MemoryStream memStream = new MemoryStream();
            //ProtoBuf.Serializer.Serialize<T>(memStream, rpc);

            Int32 len = (Int32)memStream.Length;
            int headLen = NetDefine.HEAD_LEN_SIZE;
            int opLen = NetDefine.HEAD_OP_SIZE;
            byte[] data = new byte[headLen + opLen + len];
            BitConverter.GetBytes(len).CopyTo(data, 0);
            BitConverter.GetBytes(op).CopyTo(data, headLen);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(data, 0, headLen);
                Array.Reverse(data, headLen, opLen);
            }

            memStream.ToArray().CopyTo(data, headLen + opLen);
            memStream.Close();
            SendData(data);
        }

        protected void RegisterMsg(ushort opCode, string msgType, ProtocolHandler h)
        {
            mProtocol.RegisterMsg(opCode, msgType, h);
        }

        protected virtual void InitialProtocol()
        {
        }

        protected virtual void OnConnected(object src, EventArgs arg)
        {
            PLDebug.Log("链接成功");
        }

        protected virtual void OnConnectFailed(object src, EventArgs arg)
        {
            PLDebug.Log("连接失败");
        }

        protected virtual void OnDisconnected(object src, EventArgs arg)
        {
            PLDebug.Log("断开链接");
        }

        protected virtual void ReceiveProtocol(object src, NetEventArg_Received arg)
        {
            if (mProtocol != null)
            {
                mProtocol.ReceiveProtocol(src, arg);
            }
        }
    }
}